[实例] 小球滚动
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>小球滚动</title>
<!-- React 核心库,与宿主环境无关 -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 依赖核心库,将核心功能与页面结合 -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- babel -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<style>
.ball {
background-color: red;
border-radius: 50%;
box-shadow: 0 0 25px 10px rgba(215, 215, 215, 0.5) inset;
height: 100px;
position: absolute;
width: 100px;
}
.ball::before {
background-color: #fff;
border-radius: 50%;
content: "";
display: block;
height: 12%;
left: 20%;
opacity: 0.3;
position: absolute;
top: 20%;
transform: rotate(30deg);
width: 8%;
}
.ball::after {
background-color: #fff;
border-radius: 50%;
content: "";
display: block;
height: 7%;
left: 32%;
opacity: 0.3;
position: absolute;
top: 12%;
transform: rotate(60deg);
width: 5%;
}
body {
background-color: #ffffff;
}
</style>
</head>
<body>
<div id="root"></div>
<script>
/**
* 获取随机数
* @param {number} min
* @param {number} max
* @returns {number}
*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
</script>
<!-- 小球组件 -->
<script type="text/babel">
class Ball extends React.Component {
constructor(props) {
super(props);
this.state = {
width: props.width || 100,
height: props.width || 100,
left: props.left || 0,
top: props.top || 0,
speedX: props.speedX || 200,
speedY: props.speedY || 200,
color: props.color || "red",
opacity: props.opacity || 0.9,
};
const duration = 10;
//
setInterval(() => {
let xDis = (this.state.speedX * duration) / 1000;
let yDis = (this.state.speedY * duration) / 1000;
let newLeft = this.state.left + xDis;
let newTop = this.state.top + yDis;
// 限制小球的左右移动范围
if (newLeft <= 0) {
newLeft = 0;
this.setState({
speedX: -this.state.speedX,
});
} else if (
newLeft >=
document.documentElement.clientWidth - this.state.width
) {
newLeft = document.documentElement.clientWidth - this.state.width;
this.setState({
speedX: -this.state.speedX,
});
}
// 限制小球的上下移动范围
if (newTop <= 0) {
newTop = 0;
this.setState({
speedY: -this.state.speedY,
});
} else if (
newTop >=
document.documentElement.clientHeight - this.state.width
) {
newTop = document.documentElement.clientHeight - this.state.width;
this.setState({
speedY: -this.state.speedY,
});
}
this.setState({
left: newLeft,
top: newTop,
});
}, duration);
}
render() {
return (
<>
<div
className="ball"
style={{
width: this.state.width,
height: this.state.height,
left: this.state.left,
top: this.state.top,
background: this.state.color,
opacity: this.state.opacity,
}}
></div>
</>
);
}
}
</script>
<!-- 小球列表组件 -->
<script type="text/babel">
class BallList extends React.Component {
constructor(props) {
super(props);
let timer = null;
this.state = {
list: [],
};
timer = setInterval(() => {
let list = this.state.list;
list.push({
left: getRandom(0, document.documentElement.clientWidth - 100),
top: getRandom(0, document.documentElement.clientHeight - 100),
width: getRandom(50, 200),
height: getRandom(50, 200),
speedX: getRandom(100, 300),
speedY: getRandom(100, 300),
opacity: getRandom(10, 90) / 100,
color: `rgb(${getRandom(0, 255)},${getRandom(0, 255)},${getRandom(
0,
255
)})`,
});
this.setState({
list: list,
});
if (this.state.list.length > 30) {
clearInterval(timer);
}
}, 1000);
}
render() {
return (
<>
{this.state.list.map((item, index) => (
<Ball key={index} {...item} />
))}
</>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<BallList />, document.getElementById("root"));
</script>
</body>
</html>